#ifndef __SCLINUX_H
#define __SCLINUX_H

//#define LIBDYNAMIC

#include <unistd.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pthread.h>
#include <sched.h>
#include <limits.h>

#define __MACRO_VARARGS_SUPPORTED__

#undef LIBCTOR
//#define LIBCTOR __attribute__((constructor))
#define LIBCTOR
#undef LIBDTOR
//#define LIBDTOR __attribute__((destructor))
#define LIBDTOR

#define LIBEXPORTSYMBOL
#define LIBIMPORTSYMBOL

#define MAINTYPE int
#define MAIN main
#define SCOS_MTU 1024
#define restrict
#define IABS(a)      abs(a)
#define ICLIPI(a, b) (((a)<(b))?(a):(b))

typedef pthread_mutex_t scos_mutex_t;
typedef pthread_t       scos_thread_t;
typedef pthread_key_t   scos_key_t;
typedef pthread_cond_t  scos_cond_t;
typedef int             SOCKET;

#define scos_thread_create(thread, func, arg) { pthread_attr_t attr; \
                                                pthread_attr_init(&attr); \
                                                pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); \
                                                pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + 65536); \
                                                abortOnError(STREAM(0), pthread_create(thread, &attr, func, (void*)arg)); \
                                                pthread_attr_destroy(&attr); }
#define scos_thread_create_joinable(thread, func, arg) pthread_create(thread, NULL, func, (void*)arg)
#define scos_thread_join(thread)              pthread_join(*thread, NULL)
#define scos_mutex_init(mutex)                { pthread_mutexattr_t _mattr; \
                                                pthread_mutexattr_init(&_mattr); \
                                                pthread_mutexattr_settype(&_mattr, PTHREAD_MUTEX_RECURSIVE); \
                                                pthread_mutex_init(mutex, &_mattr); }
#define scos_mutex_destroy(mutex)             pthread_mutex_destroy(mutex)
#define scos_mutex_lock(mutex)                pthread_mutex_lock(mutex)
#define scos_mutex_unlock(mutex)              pthread_mutex_unlock(mutex)
#define scos_mutex_trylock(mutex)             pthread_mutex_trylock(mutex)
#define scos_cond_init(cond)                  pthread_cond_init(cond, NULL)
#define scos_cond_wait(cond, mutex)           pthread_cond_wait(cond, mutex)
#define scos_cond_signal(cond)                pthread_cond_broadcast(cond)
#define scos_cond_destroy(cond)               pthread_cond_destroy(cond)
#define scos_self()                           pthread_self()
#define scos_gettimeofday(tv, tz)             gettimeofday(tv, tz)
#define scos_yield()                          sched_yield()
#define scos_usleep(t)                        usleep(t)
#define scos_delay(t)                          
#define scos_dissipate(e)

#define scos_socket(af, type, protocol)       socket (af, type, protocol)
#define scos_accept(s, addr, addrlen)         accept (s, addr, addrlen)
#define scos_bind(s, addr, addrlen)           bind   (s, addr, addrlen)
#define scos_connect(s, addr, addrlen)        connect(s, addr, addrlen)
#define scos_recv(s, buf, len, flags)         recv   (s, buf, len, flags)
#define scos_send(s, buf, len, flags)         send   (s, buf, len, flags)
#define scos_close(s)                         close  (s)
#define scos_listen(s, backlog)               listen (s, backlog)
#define scos_sendto(s, msg, len, flags, to, tolen) sendto (s, msg, len, flags, to, tolen)
#define scos_setsockopt(s, level, optname, optval, optlen) setsockopt (s, level, optname, optval, optlen)

#define scos_setpreempt(state)
#define scos_trace(val)

#endif /* __SCLINUX_H */
